package com.dd.ma;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.httpclient.NameValuePair;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jgroups.util.Scheduler;
import org.jgroups.util.Scheduler.Task;

public class MaUser {
	// 主线程间隔,单步间隔,出错间隔
	// http://game1-cbt.ma.sdo.com:10001/connect/app/check_inspection?cyt=1
	// http://game1-cbt.ma.sdo.com:10001/connect/app/notification/post_devicetoken?cyt=1
	// login_id=znIE3jBuHTRyadCl4lPG8A&password=N2QiXntzujsMFK3Xu2bbMQ&token=XftUvIZMJrhujzn8BFmIm3x5myUt6cuXIfXGbX652fGk5rA3AOZWlqyKbHM203fKUpJAQ1hU/fi22W9vPR7jl4fRGkHduq7h6PUy35UN0gW0Dfia0afEZ1YnNWKFf2mXI34othw9cG8rN/%2b1PPozfg
	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	// 5秒扫描一次,当前时间大于next时候才扫妖
	private long mainInterval = 5000L;
	// 两次次完整的扫妖过程基本间隔时间
	private long nextInterval = 20000L;
	private long stepInterval = 1500L;
	private long errorInterval = 3000L;
	private String phone = "";
	private String password = "";
	private String cookie = "";
	private String agent = "";
	private Hashtable done; // 打过的
	private Document resultDoc;
	private boolean running = false;
	private boolean alive = false;
	private boolean relogin = false;
	private Timer timer;
	private long next = 0L;
	private int nextrate = 1;
	public boolean isAlive() {
		return alive;
	}

	public void setAlive(boolean alive) {
		this.alive = alive;
	}

	public boolean isRelogin() {
		return relogin;
	}

	public void setRelogin(boolean relogin) {
		this.relogin = relogin;
	}

	public long getMainInterval() {
		return mainInterval;
	}

	public void setMainInterval(long mainInterval) {
		this.mainInterval = mainInterval;
	}

	public long getStepInterval() {
		return stepInterval;
	}

	public void setStepInterval(long stepInterval) {
		this.stepInterval = stepInterval;
	}

	public long getErrorInterval() {
		return errorInterval;
	}

	public void setErrorInterval(long errorInterval) {
		this.errorInterval = errorInterval;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getCookie() {
		return cookie;
	}

	public void setCookie(String cookie) {
		this.cookie = cookie;
	}

	public String getAgent() {
		return agent;
	}

	public void setAgent(String agent) {
		this.agent = agent;
	}

	public void startProcess() {
		alive = true;
		if (timer == null) {
			timer = new Timer();
		}
		running = false;
		timer.scheduleAtFixedRate(new MaTask(), 3000, mainInterval);
	}

	public void stopProcess() {
		alive = false;
		if (timer != null) {
			timer.cancel();
			timer = null;
			running = false;
		}

	}

	class MaTask extends TimerTask {

		public void run() {
			if (running) {
				// 上次还没运行完
				return;
				// MaUtil.printMsg(phone, "上次线程还没运行完");
			} else {
				running = true;
				long nextTime = nextInterval;
				if (System.currentTimeMillis() < next) {
					// 下次运行时间未到
					running = false;
					return;
				}
				String startDate = "本次进程开始时间:" + df.format(new Date());
				try {
					MaUtil.printMsg(phone, startDate + ",定时器开始运行......");
					NameValuePair[] data = {};
					// 第一步取菜单
					MaUtil.printMsg(phone, "模拟点击菜单......使用cookie:" + cookie);
					PostAction menuAction = new PostAction(MaUtil.MENU_URL,
							cookie, agent);
					String res = menuAction.getActionResponse(data);
					Thread.sleep(stepInterval);
					// 第二步,选择妖精
					MaUtil.printMsg(phone, "模拟点击妖精......(返回的结果只处理战斗中的)");
					PostAction selectAction = new PostAction(MaUtil.SELECT_URL,
							cookie, agent);
					res = selectAction.getActionResponse(data);
					Thread.sleep(stepInterval);
					resultDoc = DocumentHelper.parseText(res);
					List<Element> fairy_event = resultDoc.getRootElement()
							.element("body").element("fairy_select").elements(
									"fairy_event");
					// 打印妖精信息,保存mu中
					// List<Fairy> list = new ArrayList<Fairy>();
					int fuckfairy = 0;
					int battleingfairy = 0;
					for (int i = fairy_event.size() - 1; i > 0; i--) {
						Element fairy = fairy_event.get(i);
						String fairy_put_down = fairy.element("put_down")
								.getText();
						if (fairy_put_down.equals("2")) {
							continue;
						}

						String user_id = fairy.element("user").element("id")
								.getText();
						String user_name = fairy.element("user")
								.element("name").getText();
						String fairy_serial_id = fairy.element("fairy")
								.element("serial_id").getText();
						String fairy_lv = fairy.element("fairy").element("lv")
								.getText();
						String fairy_name = fairy.element("fairy").element(
								"name").getText();

						String strat_time = fairy.element("start_time")
								.getText()
								+ "000";
						if (done == null) {
							done = new Hashtable();
						}
						battleingfairy++;
						if (done.containsKey(fairy_serial_id)) {
							MaUtil.printMsg(phone, "跳过已舔妖精--好友:" + user_name
									+ " 妖精:" + fairy_name + "LV" + fairy_lv+" DOWN"+fairy_put_down);
						} else {
							MaUtil.printMsg1(phone, df.format(new Date())
									+ ":发现可舔妖精--好友:" + user_name + " 妖精:"
									+ fairy_name + "LV" + fairy_lv+" DOWN"+fairy_put_down);
							MaUtil.printMsg(phone, "模拟点击查看妖精详情......");
							// 第三步 模拟查看妖精 (floor)
							NameValuePair[] data1 = {
									new NameValuePair("check", MaUtil
											.getSndaRequestString("1")),
									new NameValuePair(
											"serial_id",
											MaUtil
													.getSndaRequestString(fairy_serial_id)),
									new NameValuePair("user_id", MaUtil
											.getSndaRequestString(user_id)) };
							PostAction floorAction = new PostAction(
									MaUtil.FLOOR_URL, cookie, agent);
							res = floorAction.getActionResponse(data1);
							Thread.sleep(stepInterval);
							MaUtil.printMsg(phone, "模拟舔妖精......");
							// 第三步 模拟舔妖精
							NameValuePair[] data2 = {
									new NameValuePair(
											"serial_id",
											MaUtil
													.getSndaRequestString(fairy_serial_id)),
									new NameValuePair("user_id", MaUtil
											.getSndaRequestString(user_id)) };
							PostAction battleAction = new PostAction(
									MaUtil.BATTLE_URL, cookie, agent);
							res = battleAction.getActionResponse(data2);
							//舔妖战斗间隔用单步间隔的3倍
							Thread.sleep(stepInterval*3);
							resultDoc = DocumentHelper.parseText(res);
							String code = resultDoc.getRootElement().element(
									"header").element("error").element("code")
									.getText();
							if (!code.equals("0")) {
								MaUtil.printMsg1(phone, "舔妖精失败......原因:"
										+ resultDoc.getRootElement().element(
										"header").element("error")
										.element("code").getText()+"---"+resultDoc.getRootElement().element(
												"header").element("error")
												.element("message").getText());
							} else {
								// 舔成功就直接下一轮不舔第二个,容易出错
								fuckfairy++;
								//没打赢
								if(res.indexOf("<winner>1</winner>")==-1){
									MaUtil.printMsg1(phone, "舔妖精成功,没推到......");
									MaUtil.printMsg(phone, "模拟battlelose......");
									
									PostAction loseAction = new PostAction(
											MaUtil.BATTLE_LOSE, cookie, agent);
									res = loseAction.getActionResponse(data2);
									Thread.sleep(stepInterval);
								}else{
									MaUtil.printMsg1(phone, "舔妖精成功并推到......");
								}
								done.put(fairy_serial_id, "好友:" + user_name
												+ " 妖精:" + fairy_name + "LV"
												+ fairy_lv);
								
								i = 0;
							}
							
						}
					}
					//舔到妖
					if (fuckfairy > 0) {
						MaUtil.printMsg(phone, "本次定时器结束......舔了" + fuckfairy
								+ "只");
						MaUtil
								.printMsg(
										phone,
										"====================================================================================");
						nextrate=1;
					//没舔到
					} else {
						//有战斗中的妖
						if(battleingfairy>0){
							nextrate=2;
							
							MaUtil.printMsg(phone, "本次定时器结束......没妖精可以舔,延长定时器间隔("+nextrate+")倍");
							nextTime= nextInterval*nextrate;
							MaUtil
									.printMsg(
											phone,
											"====================================================================================");
							//没有战斗中的妖
						}else{
							nextrate++;
							if(nextrate>5){
								nextrate = 5+new Random().nextInt(5);
							}
							MaUtil.printMsg(phone, "本次定时器结束......没战斗中的妖精,随机延长定时器间隔("+nextrate+")倍");
							nextTime= nextInterval*nextrate;
							MaUtil
									.printMsg(
											phone,
											"====================================================================================");
						}
					}
				} catch (ServerDownException e) {
					MaUtil.printMsg(phone, startDate
							+ ":扫描过程中出现1020错误,服务器正在维护,下次运行时间推后5分钟.....");
					
					nextTime = 300000L;
				} catch (ServerErrorException e) {
					// code 9000 错误

					if (relogin) {
						MaUtil
								.printMsg(
										phone,
										startDate
												+ ":扫描过程中出现9000错误,链接超时回到首页,配置重新登陆,用用户名和密码登陆重新获取cookie中.....");
						resetCookieStr();

					} else {
						MaUtil.printMsg(phone, startDate
								+ ":扫描过程中出现9000错误,链接超时回到首页,配置不重新登陆,跳出");
						timer.cancel();
						alive = false;
					}
					// e.printStackTrace();
				} catch (Exception e) {
					MaUtil.printMsg(phone, startDate
							+ ":扫描过程中出现未知错误,本次跳过,错误信息:" + e.getMessage());
					e.printStackTrace();
				} finally {
					next = System.currentTimeMillis() + nextTime;
					running = false;
				}
			}
		}

	}

	private void resetCookieStr() {
		String cookiestr = "";
		try {
			// MaUtil.printMsg("模拟登陆......");
			PostAction LoginAction = new PostAction(MaUtil.LONIN_URL, cookie,
					agent);
			NameValuePair[] data1 = {
					new NameValuePair("login_id", MaUtil
							.getSndaRequestString(phone)),
					new NameValuePair("password", MaUtil
							.getSndaRequestString(password)) };
			String res = LoginAction.getActionResponse(data1);
			int pos1 = res.indexOf("<session_id>");
			int pos2 = res.indexOf("</session_id>");
			cookiestr = res.substring(pos1 + 12, pos2);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (cookiestr.length() > 5) {
			this.cookie = "S=" + cookiestr;
		}

	}

}
